﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;

#endregion

namespace ScrumTable.Common.Collections
{
    /// <summary>
    /// Specifies a read only wrapper for the IDictionary&lt;TKey, TValue&gt;
    /// interface.
    /// </summary>
    /// <remarks>
    /// Changing the content of the collection is not supported.
    /// </remarks>
    public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        private readonly IDictionary<TKey, TValue> _inner;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        ///  <see cref="IDictionary{TKey,TValue}.Keys"/>
        /// </summary>
        public ICollection<TKey> Keys
        {
            get { return _inner.Keys; }
        }

        /// <summary>
        ///  <see cref="IDictionary{TKey,TValue}.Values"/>
        /// </summary>
        public ICollection<TValue> Values
        {
            get { return _inner.Values; }
        }

        /// <summary>
        ///  <see cref="IDictionary{TKey,TValue}.get_Item"/>
        /// </summary>
        /// <remarks>
        /// Changing the content of the collection is not supported.
        /// </remarks>
        public TValue this[TKey key]
        {
            get { return _inner[key]; }
            set { throw new NotSupportedException(); }
        }

        /// <summary>
        ///  <see cref="ICollection{T}.Count"/>
        /// </summary>
        public int Count
        {
            get { return _inner.Count; }
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        public bool IsReadOnly
        {
            get { return true; }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new ReadOnlyDictionary instance with the specified data.
        /// </summary>
        /// <param name="inner">Specifies the collection to wrap.</param>
        public ReadOnlyDictionary(IDictionary<TKey, TValue> inner)
        {
            PreCondition.AssertNotNull(inner, "inner");

            _inner = inner;
        }

        /// <summary>
        /// Creates a new ReadOnlyDictionary instance without data.
        /// </summary>
        public ReadOnlyDictionary()
        {
            _inner = new Dictionary<TKey, TValue>(0);
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        ///  <see cref="IEnumerable{T}.GetEnumerator"/>
        /// </summary>
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return _inner.GetEnumerator();
        }

        /// <summary>
        ///  <see cref="IEnumerable{T}.GetEnumerator"/>
        /// </summary>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return ((System.Collections.IEnumerable)_inner).GetEnumerator();
        }

        /// <summary>
        ///  <see cref="IDictionary{TKey,TValue}.ContainsKey"/>
        /// </summary>
        public bool ContainsKey(TKey key)
        {
            return _inner.ContainsKey(key);
        }

        /// <summary>
        ///  <see cref="ICollection{T}.Contains"/>
        /// </summary>
        public bool Contains(KeyValuePair<TKey, TValue> item)
        {
            return _inner.Contains(item);
        }

        /// <summary>
        ///  <see cref="ICollection{T}.CopyTo"/>
        /// </summary>
        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            _inner.CopyTo(array, arrayIndex);
        }

        /// <summary>
        ///  <see cref="IDictionary{TKey,TValue}.TryGetValue"/>
        /// </summary>
        public bool TryGetValue(TKey key, out TValue value)
        {
            return _inner.TryGetValue(key, out value);
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        void ICollection<KeyValuePair<TKey, TValue>>.Clear()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Changing the content of the collection is not supported.
        /// </summary>
        bool IDictionary<TKey, TValue>.Remove(TKey key)
        {
            throw new NotSupportedException();
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}